/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.vng.session.client;

import com.vng.jcore.thriftutil.TClientPool;
import com.vng.jcore.thriftutil.TClientPoolConfig;
import com.vng.jcore.thriftutil.TClientPoolMan;
import com.vng.session.thrift.SessionRead;
import com.vng.session.thrift.SessionResult;
import com.vng.zing.lib.Config;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.cliffc.high_scale_lib.NonBlockingHashMap;

/**
 *
 * @author kienpd
 */
public class SessionClient {

    private static final Lock createLock_ = new ReentrantLock();
    private static final Map<String, SessionClient> _instances = new NonBlockingHashMap();
    private static final String host = Config.getParamStr("session_server", "host") ;
    private static final int  port = Config.getParamInt("session_server", "port");
    private TClientPool<SessionRead.Client> Pool;

    public static SessionClient getInstance() {
        String key = String.format("%s:%s", new Object[]{host, port});

        if (!_instances.containsKey(key)) {
            createLock_.lock();
            try {
                if (_instances.get(key) == null) {
                    _instances.put(key, new SessionClient());
                }
            } finally {
                createLock_.unlock();
            }
        }
        return _instances.get(key);
    }

    private SessionClient() {
        TClientPoolConfig.ConnConfig conn_cfg = new TClientPoolConfig.ConnConfig(host, port, true, false, 0);

        // get current pool
        Pool = (TClientPool<SessionRead.Client>) TClientPoolMan.Instance.getPool(host, port, SessionRead.Client.class);
        if (Pool == null) {
            // add client to pool
            TClientPoolMan.Instance.addPool(
                    new TClientPool<SessionRead.Client>(
                            new SessionRead.Client.Factory(), conn_cfg, TClientPoolConfig.DefaultPoolConfig));
            // get current pool
            Pool = (TClientPool<SessionRead.Client>) TClientPoolMan.Instance.getPool(host, port, SessionRead.Client.class);
        }
        assert (Pool != null);

    }

    public SessionResult GetSession(String sessionId) throws Exception {
        SessionResult result;
        SessionRead.Client cli = null;
        try {
            // get client
            cli = Pool.borrowClient();
            assert (cli != null);
            result = cli.GetSession(sessionId);
            //Return client back to pool
            Pool.returnObject(cli);
        } catch (Exception ex) {
            Pool.invalidObjExless(cli);
            throw ex;
        }
        return result;

    }
  
}
